package ch.headshot.photomap.client;

import java.util.List;

import ch.headshot.photomap.client.gpx.Gpx;
import ch.headshot.photomap.client.gpx.Link;
import ch.headshot.photomap.client.gpx.Route;
import ch.headshot.photomap.client.gpx.Track;
import ch.headshot.photomap.client.gpx.TrackSegment;
import ch.headshot.photomap.client.gpx.WayPoint;
import ch.headshot.photomap.client.gpx.impl.GpxImpl;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.http.client.URL;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.control.LargeMapControl;
import com.google.gwt.maps.client.control.MapTypeControl;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.maps.client.overlay.Polyline;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.xml.client.XMLParser;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Photomap implements EntryPoint {

	private MapWidget map;

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {

		map = new MapWidget();
		map.setSize("100%", "100%");
		map.setZoomLevel(10);
		map.setCenter(LatLng.newInstance(46.294369698, 7.836320400));
		map.setInfoWindowEnabled(true);

		// Add some controls for the zoom level
		map.addControl(new LargeMapControl());
		map.addControl(new MapTypeControl());

		// Add the map to the HTML host page
		RootPanel.get().add(map);

		// readGPX("rhoneWanderung.xml");
		readGPX("rhoneWanderung.xml2");
	}

	private void readGPX(String url) {

		RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL.encode(url));

		try {
			Request request = builder.sendRequest(null, new RequestCallback() {
				public void onError(Request request, Throwable exception) {
					GWT.log("faild to read gpx", exception);
					Window.alert(exception.getMessage());
				}

				public void onResponseReceived(Request request, Response response) {
					if (200 != response.getStatusCode()) {
						GWT.log("faild to read gpx: " + response.getStatusText(), null);
						Window.alert("failed");
					} else {

						Gpx gpx = new GpxImpl(XMLParser.parse(response.getText()).getDocumentElement());

						for (WayPoint wpt : gpx.getWayPoints()) {
							addOverLay(wpt);
						}

						for (Route route : gpx.getRoutes()) {
							addOverlay(route.getPoints());
						}

						for (Track track : gpx.getTracks()) {
							for (TrackSegment segment : track.getSegments()) {
								addOverlay(segment.getPoints());
							}
						}

					}
				}

				private void addOverLay(WayPoint point) {
					for (Link link : point.getLinks()) {
						addMarker(LatLng.newInstance(point.getLatitude(), point.getLongitude()), point.getLinks().get(0).getHref());
					}
				}

				private void addOverlay(List<WayPoint> points) {
					LatLng[] latLngs = new LatLng[points.size()];
					for (int i = 0; i < latLngs.length; i++) {
						WayPoint point = points.get(i);
						latLngs[i] = LatLng.newInstance(point.getLatitude(), point.getLongitude());
						// addMarker(latLngs[i]);
					}
					map.addOverlay(new Polyline(latLngs, "#FF0000"));
					// EncodedPolyline dpEncode = new
					// PolylineEncoder().dpEncodeToPolyLine(points);
					// map.addOverlay(Polyline.fromEncoded(dpEncode));
				}

				private void addMarker(LatLng latLng, final String url) {

					map.addOverlay(new Photomarker(latLng, url, map));
				}

			});
		} catch (RequestException e) {
			GWT.log("faild to read gpx", e);
		}

	}
}
